/*****************************************************************************/
/*                                                                           */
/* Version:  2.00   Date:  20/09/02   File: main.c                           */
/* Author:  Marco Chiarandini                                                */
/* email: machud@intellektik.informatik.tu-darmstadt.de                      */
/*                                                                           */
/*****************************************************************************/
/*                                                                           */
/*===========================================================================*/

#include <getopt.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "test_sol.h"
 
#define LINE_BUF_LEN     1000

static int     opt;
static char    name_buf[LINE_BUF_LEN];
static char    sol_buf[LINE_BUF_LEN];

long int checkConstraints()
{
    FILE     *col_file;
    char     buf [LINE_BUF_LEN];
    char     *p, *buf_pos;
    long int  from = 0, to = 0, reading_flag;
    long int num_of_viol;
    /*long int i;*/
    NUM_EDGES = 0;

    printf("\nreading coloring-problem-file %s ... \n\n", instance_name);

    col_file = fopen(instance_name, "r");
    assert(col_file != NULL);
    reading_flag = TRUE;
    num_of_viol=0;
    while (!feof(col_file)) {
	reading_flag = FALSE;
	buf[0] = '\0';
	fgets((char*) &buf, LINE_BUF_LEN, col_file);
	if ((p=strstr((char*)(&buf), "c"))!=NULL) {    /* If a c is found in a line, it's part of header */
	    printf("%s", buf); 
	}
	else if ((p=strstr((char*)(&buf), "p"))!=NULL){  /* This is the line with the problem dimension */
	    printf("%s", buf); 
	    /*	    printf("reading parameter line ...\n");*/
	    if(strstr((char*)&buf,"edge")!=NULL) {
		p++;
		while(*p != '\0' && *p != '\n'){
		    while(*p == ' ')
			p++;
		    while(*p != ' ')
			p++;
		    while(*p == ' ')
			p++;
		    NUM_NODES = atol(p);
		    /*constraints_matrix = allocateMatrix( NUM_NODES, NUM_NODES);*/
		    solution_vector = allocateVector(NUM_NODES);
		    readSolution();
		    num_of_viol=0;
		    while(*p != ' ')
			p++;
		    while(*p == ' ')
			p++;
		    *p = '\0';
		}
	    }      
	}
	else if ((p=strstr((char*)(&buf), "e"))!=NULL) {  /* This is a line with an edge */
	    p++;
	    while(*p != '\0' && *p != '\n'){
		while(*p == ' ')
		    p++;
		buf_pos = p;
		while(*p != ' ' && *p != '\n' && *p != '\0' )
		    p++;
		*p = '\0';
		from = atol(buf_pos);
		p++;
		while(*p == ' ')
		    p++;
		buf_pos = p;
		to = atol(buf_pos);
		*p = '\0';
	    }
	    
	    if (wap_instance)
	      {
		from++;
		to++;
	      }
	    
	    assert ( (1 <= from) && (from <=NUM_NODES));
	    assert ( (1 <= to) && (to <= NUM_NODES));
	    /*   constraints_matrix[from][to] = 1;
		 constraints_matrix[to][from] = 1;*/
	    if (solution_vector[from] == solution_vector[to])
	      num_of_viol++;
	    NUM_EDGES++;
	}
    }
    fclose(col_file);
   
    /*    for (i = 0; i<=NUM_NODES; i++)
	  free(constraints_matrix[i]);*/
    /*free(constraints_matrix);*/
    free(solution_vector);
    
    DENSITY = ((float)(NUM_EDGES))/((NUM_NODES/2)*(NUM_NODES-1));  

    return num_of_viol;
}

void usage() {
  fprintf(stderr,"\nSOLUTION TEST for Graph Coloring, V2.00\n");
  fprintf(stderr,"usage: test [- see below -] [dat_file] (given are short options)\n");
  fprintf(stderr,"--benchfile       -f f\t inputfile (DIMACS format necessary)\n");
  fprintf(stderr,"                         nodes go from 1 to N\n");
  fprintf(stderr,"--solution        -s f\t solution file (see below)\n");
  fprintf(stderr,"--wap_instance    -w  \t indicate the instance is of the kind wap*.col\n");
  fprintf(stderr,"--help            -h  \t help: prints this information\n\n");
  fprintf(stderr,"Solution File Format: colors assigned to nodes are wrote in column.\n");
  fprintf(stderr,"After each entry the character \\n (new line) has to be printed.\n"); 
  fprintf(stderr,"Colors start from 1 and the first color in the column represent\n");
  fprintf(stderr,"the color assigned to node 1. \n");
 
}

void checkOptions( long int argc, char *argv[])
{
  while (1) {
    int option_index = 0;
   
    static struct option long_options[] = {
      {"benchfile",       1, 0, 'f'},
      {"solution",        1, 0, 's'},
      {"wap",             1, 0, 'w'},
      {"help",        	  0, 0, 'h'},
      {0,             	  0, 0,  0 }
    };


    opt = getopt_long(argc, argv, "f:s:hw",long_options, &option_index);
    if ( opt == -1 )
	break;
    
    switch ( opt ){
	case 0:
	    fprintf(stderr,"Error: Confused by input on long option...\n");
	    exit(1);
	    break;
	    
	case 'f':
	    strncpy( name_buf, optarg, strlen( optarg )+1 );
	    strncpy( instance_name, name_buf, strlen( name_buf ) );
	    break;
	    
	case 's':
	    strncpy( sol_buf, optarg, strlen( optarg ) +1);
	    strncpy( solution_name, sol_buf, strlen( sol_buf ) );
	    break;
    case 'w':
      wap_instance = TRUE;
      break;

	case 'h':
	    usage();
	    fprintf(stderr,/*"No more help yet, sorry.\n*/"\n"), exit(1);
	    break;
	    
	default:
	    fprintf(stderr,"Error: Confused by input...\n"), exit(1);
	    
    }
  }
}
/*
long int count_violations ()
{
    long int	  i,l;
    long int violations;
   
    violations = 0;

    for (i = 1; i <= NUM_NODES; i++) {
	for (l = i; l <= NUM_NODES; l++) {
	    if ( (constraints_matrix[i][l]!=0) 
		 && (solution_vector[i] == solution_vector[l]) ) {
		violations++;
	    }
	}
    }
    return violations;
}
*/

void readSolution()
{
    FILE     *sol_file;
    long int node;
    long int col;

    sol_file = fopen(solution_name, "r");
    assert(sol_file != NULL);

    node = 1;
    NUM_COL = 0;

    while (EOF != fscanf(sol_file,"%ld",&col))
    {
	solution_vector[node]=col;
	node ++;
	if (col > NUM_COL)
	    NUM_COL = col;
    }
    NUM_COL++;
    fclose(sol_file);
}	

   
long int **allocateMatrix(long int rows, long int cols)
{
  long int i;
  long int **matrix;

    matrix = (long int **) malloc((rows+1) * sizeof(long int *));
    if (matrix == NULL)
    {
	fprintf(stderr,"Problems in memory allocation\n");
    }
    for (i=0; i < (rows+1) ;i++)
    {
	matrix[i] = (long int *) malloc((cols+1) * sizeof(long int));
	if (matrix[i] == NULL)
	{
	    fprintf(stderr,"Problems in memory allocation\n");
	}
	memset(matrix[i], 0, (cols+1)*sizeof(long int));
    }
    return matrix;
}

long int *allocateVector(long int size)
{
  long int *vector;

    vector = (long int *) malloc((size+1) * sizeof(long int ));
    if (vector == NULL)
    {
	fprintf(stderr,"Problems in memory allocation\n");
    }
    memset(vector, 0, (size+1)*sizeof(long int));
    return vector;
}





